package raft

import (
	"context"
	"encoding/json"
	"log"
)

func (n *RaftNode) AddServer(ctx context.Context, req *ServerReq) (*ServerResp, error) {
	n.mu.Lock()
	defer n.mu.Unlock()

	if n.state != Leader {
		return &ServerResp{Success: false}, nil
	}

	// 构建配置变更命令
	cmd := map[string]interface{}{
		"type": "add_server",
		"id":   req.ServerId,
		"addr": req.Address,
	}

	cmdData, _ := json.Marshal(cmd)

	// 添加到日志
	n.appendCommand(cmdData)

	return &ServerResp{Success: true}, nil
}

func (n *RaftNode) RemoveServer(ctx context.Context, req *ServerReq) (*ServerResp, error) {
	n.mu.Lock()
	defer n.mu.Unlock()

	if n.state != Leader {
		return &ServerResp{Success: false}, nil
	}

	// 构建配置变更命令
	cmd := map[string]interface{}{
		"type": "remove_server",
		"id":   req.ServerId,
	}

	cmdData, _ := json.Marshal(cmd)

	// 添加到日志
	n.appendCommand(cmdData)

	return &ServerResp{Success: true}, nil
}

func (n *RaftNode) applyConfigChange(cmd []byte) {
	var change struct {
		Type string `json:"type"`
		ID   int32  `json:"id"`
		Addr string `json:"addr,omitempty"`
	}

	if err := json.Unmarshal(cmd, &change); err != nil {
		log.Printf("Invalid config change command: %v", err)
		return
	}

	switch change.Type {
	case "add_server":
		if _, exists := n.peers[change.ID]; !exists {
			n.peers[change.ID] = NewPeer(change.ID, change.Addr, n)
			n.nextIndex[change.ID] = n.lastLogIndex() + 1
			n.matchIndex[change.ID] = 0
			log.Printf("Node %d added server %d at %s", n.id, change.ID, change.Addr)
		}
	case "remove_server":
		if peer, exists := n.peers[change.ID]; exists {
			delete(n.peers, change.ID)
			delete(n.nextIndex, change.ID)
			delete(n.matchIndex, change.ID)
			peer.Close()
			log.Printf("Node %d removed server %d", n.id, change.ID)
		}
	}
}
